const path = require('path');

const pageBuildPath = path.join(__dirname, '..');

// 项目根目录
exports.rootPath = path.join(__dirname, '..');

exports.resolve = function (dir) {
  return path.join(exports.rootPath, dir);
};

exports.getName = function (chunkName, ext, hashName, DEV_MODE) {
  return (
    chunkName +
    '/' +
    chunkName +
    (DEV_MODE ? '.' : '-[' + (hashName ? hashName : 'contenthash') + ':9].') +
    ext
  );
};

exports.getResourceName = function (DEV_MODE) {
  return exports.getName('[path][name]', '[ext]', 'hash', DEV_MODE);
};

exports.getResolveLoader = function (data) {
  return {
    modules: [
      'node_modules',
      path.join(data.gitLoacl, 'node_modules'),
      path.join(pageBuildPath, 'node_modules'),
    ],
  };
};

exports.getResolve = function (data, config) {
  const _config = {
    extensions: [
      '.tsx',
      '.ts',
      '.js',
      '.jsx',
      '.jsx',
      '.vue',
      '.json',
    ],
    ...exports.getResolveLoader(data),
    alias: {
      '@': path.join(data.gitLoacl, 'src'),
      Main: path.join(data.mainPath, 'main.js'),
      //components: .resolve('app/components'),
    },
  };
  if (config.alias) _config.alias = { ...config.alias, ..._config.alias };
  return _config;
};

exports.getVueLoader = function () {
  return {
    test: /\.vue$/,
    loader: 'vue-loader',
  };
};

function loaderFile(reg, limit, filepath) {
  return {
    test: reg,
    use: [
      {
        loader: 'url-loader',
        options: {
          limit: limit,
          esModule: false,
          fallback: {
            loader: 'file-loader',
            options: {
              esModule: false,
              name: filepath + '/[name].[hash:8].[ext]',
            },
          },
        },
      },
    ],
  };
}

exports.getImageLoader = function () {
  return loaderFile(/\.(png|jpe?g|gif|svg|webp)$/, '4096', 'img');
};

exports.getMediaLoader = function () {
  return loaderFile(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, '4096', 'media');
};

exports.getFontsLoader = function () {
  return loaderFile(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i, '4096', 'fonts');
};

exports.getSvgLoader = function () {
  return {
    test: /\.(svg)(\?.*)?$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          name: 'img/[name].[hash:8].[ext]',
        },
      },
    ],
  };
};

const postcssOptions = function (devMode, config) {
  let options = {
    sourceMap: devMode
  }
  if (config.postcssConfig) {
    options = Object.assign({}, options, config.postcssConfig)
    if (options.plugins) {
      options.plugins = (function (plugins) {
        const _plugins = [];
        for (const key in plugins) {
          const element = plugins[key];
          _plugins.push(require(key)(element))
        }
        return function (loader) {
          return _plugins
        }
      })(options.plugins)
    }
    return options
  }
}

exports.postcssOptions = postcssOptions;

exports.getCssLoader = function (devMode, config) {

  const rules = function (moduels) {
    const obj = [
      {
        loader: 'css-loader',
        options: {
          sourceMap: devMode,
          importLoaders: 2,
          ...moduels
        },
      },
      {
        loader: 'postcss-loader',
        options: postcssOptions(devMode, config)
      },
    ];
    if (!devMode)
      obj.splice(0, 0, {
        loader: require('mini-css-extract-plugin').loader,
        options: {
          hmr: false,
          publicPath: '../',
        },
      });
    else obj.splice(0, 0, {
      loader: 'vue-style-loader',
    });
    return obj;
  }


  return {
    test: /\.css$/,
    oneOf: [
      {
        resourceQuery: /module/,
        use: rules({
          modules: {
            localIdentName: '[name]_[local]_[hash:base64:5]'
          }
        }),
      },
      {
        resourceQuery: /\?vue/,
        use: rules({}),
      },
      {
        test: /\.module\.\w+$/,
        use: rules({
          modules: {
            localIdentName: '[name]_[local]_[hash:base64:5]'
          }
        }),
      },
      {
        use: rules(),
      },
    ],
  };
};
exports.getLessLoader = function (devMode, config) {
  const rules = function (moduels) {
    const obj = [
      {
        loader: 'css-loader',
        options: {
          sourceMap: devMode,
          importLoaders: 2,
          ...moduels
        },
      },
      {
        loader: 'postcss-loader',
        options: postcssOptions(devMode, config)
      },
      {
        loader: 'less-loader',
        options: {
          sourceMap: devMode,
        },
      },
    ];

    if (!devMode)
      obj.splice(0, 0, {
        loader: require('mini-css-extract-plugin').loader,
        options: {
          hmr: false,
          publicPath: '../',
        },
      });
    else obj.splice(0, 0, {
      loader: 'vue-style-loader',
    });
    return obj
  }
  return {
    test: /\.less$/,
    oneOf: [
      {
        resourceQuery: /module/,
        use: rules({
          modules: {
            localIdentName: '[name]_[local]_[hash:base64:5]'
          }
        }),
      },
      {
        resourceQuery: /\?vue/,
        use: rules({}),
      },
      {
        test: /\.module\.\w+$/,
        use: rules({
          modules: {
            localIdentName: '[name]_[local]_[hash:base64:5]'
          }
        }),
      },
      {
        use: rules(),
      },
    ]
  };
};

const babelOptions = function (config) {
  return Object.assign({}, { cwd: exports.rootPath }, config.babelConfig);
}

exports.getTsLoader = function (data, config) {
  // exclude: {
  //   not: [/node_modules\/swiper/, /node_modules\/dom7/],
  //   or: [/(node_modules|bower_components)/]
  // },
  return [
    // {
    //   test: /\.js$/,
    //   //exclude: [/(node_modules|bower_components)/, { not: [/node_modules\/swiper/] }, { not: [/node_modules\/dom7/] }],

    //   //[/(node_modules|bower_components)/, { not: [/node_modules\/swiper/] }, { not: [/node_modules\/dom7/] }],
    //   loader: 'babel-loader',
    //   options: babelOptions(config),
    // },
    {
      test: /\.jsx?$/,
      exclude: function (filepath) {
        // always transpile js in vue files
        if (/\.vue\.jsx?$/.test(filepath)) {
          return false
        }
        // exclude dynamic entries from cli-service
        // if (filepath.startsWith(cliServicePath)) {
        //   return true
        // }

        // only include @babel/runtime when the @vue/babel-preset-app preset is used
        if (
          process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME &&
          filepath.includes(path.join('@babel', 'runtime'))
        ) {
          return false
        }

        // check if this is something the user explicitly wants to transpile
        if (/(swiper|dom7)/.test(filepath)) {
          return false
        }
        // Don't transpile node_modules
        return /node_modules/.test(filepath)
      },
      loader: 'babel-loader',
      options: babelOptions(config),
    },
    {
      test: /\.ts$/,
      exclude: /(node_modules|bower_components)/,
      use: [
        // {
        //   loader: 'thread-loader',
        // },
        {
          loader: 'babel-loader',
          options: babelOptions(config),
        },
        {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
            appendTsSuffixTo: ['\\.vue$'],
            happyPackMode: true,
            context: data.gitLoacl,
            configFile: require.resolve(
              '../../../_gittmp_/xt-promotion/tsconfig',
            ),
            getCustomTransformers: function () {
              /* omitted long function */
            },
            compilerOptions: {
              module: 'es2015',
            },
          },
        },
      ],
    },
    /* config.module.rule('tsx') */
    {
      test: /\.tsx$/,
      exclude: /(node_modules|bower_components)/,
      use: [
        // {
        //   loader: 'thread-loader',
        // },
        {
          loader: 'babel-loader',
          options: babelOptions(config),
        },
        {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
            happyPackMode: true,
            context: data.gitLoacl,
            configFile: require.resolve(
              '../../../_gittmp_/xt-promotion/tsconfig',
            ),
            appendTsxSuffixTo: ['\\.vue$'],
          },
        },
      ],
    },
  ];
};

/*
// 项目根目录
exports.rootPath = path.join(__dirname, '..', '..');

exports.resolve = function (dir) {
  return path.join(exports.rootPath, dir);
};
// 发布路径
exports.buildPath = exports.resolve('_build_');
tools.mkdir(exports.buildPath);
// 发布路径
exports.publishPath = exports.resolve('_publish_');
tools.mkdir(exports.publishPath);

const LOADER = {
  STYLE_LOADER: 'style-loader',
  CSS_LOADER: 'css-loader',
  POSTCSS_LOADER: 'postcss-loader',
  IGNORE_LOADER: 'ignore-loader',
  URL_LOADER: 'url-loader',
  FILE_LOADER: 'file-loader',
  BABEL_LOADER: 'babel-loader',
};

const ENTRY_NAME = {
  APP: 'main',
  VENDORS: 'vendors',
  RUNTIME: 'runtime',
  APP_JS: 'main.js',
  VENDORS_JS: 'vendors.js',
  RUNTIME_JS: 'runtime.js',
};

exports.ENTRY_NAME = ENTRY_NAME;
exports.LOADER = LOADER;
exports.getName = function (chunkName, ext, hashName, DEV_MODE) {
  return (
    chunkName +
    '/' +
    chunkName +
    (DEV_MODE ? '.' : '-[' + (hashName ? hashName : 'contenthash') + ':9].') +
    ext
  );
};


exports.getStyleLoaders = function (devMode, ...loaders) {
  const temp = [];
  for (let i = 0, length = loaders.length; i < length; i++) {
    let loader = loaders[i];
    const loaderOptions = loader.options || {};
    if (loader.loader) {
      loader = loader.loader;
    }
    let tempLoader = {
      loader,
      options: {
        sourceMap: devMode,
        ...loaderOptions,
      },
    };
    if (loader === LOADER.STYLE_LOADER) {
      delete tempLoader.options.sourceMap;
    }
    temp.push(tempLoader);
  }
  // console.log(temp);
  return temp;
};

exports.normalizePublicPath = function (publicPath) {
  return publicPath === '.' ? '' : publicPath;
};
exports.normalizeTailSlash = function (publicPath, withSlash) {
  if (publicPath.endsWith('/')) {
    publicPath = withSlash
      ? publicPath
      : publicPath.substring(0, publicPath.length - 1);
  } else {
    publicPath = withSlash ? publicPath + '/' : publicPath;
  }
  if (exports.isWindows()) {
    publicPath = exports.replaceBackwardSlash(publicPath);
  }
  return publicPath;
};

exports.isWindows = function () {
  return process.platform === 'win32';
};
exports.replaceBackwardSlash = function (str) {
  return str.replace(SLASH_REGEX, '/');
};
exports.getCSSLoaderExtract = function (devMode = false) {
  return {
    use: exports.getStyleLoaders(
      devMode,
      LOADER.CSS_LOADER,
      LOADER.POSTCSS_LOADER,
    ),
    fallback: LOADER.STYLE_LOADER,
  };
};



*/
